
/*
This file is part of MJIN2.

Copyright (C) 2012-2013 Opensource Game Studio

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/

#ifndef MJIN2_PRIV_WINDOW_H
#define MJIN2_PRIV_WINDOW_H

#include <mjin2/VideoInfo.h>
#include <mjin2/WindowConfig.h>
#include <mjin2/priv/Viewer.h>
#include <mjin2/priv/WindowClose.h>
#include <mjin2/priv/WindowGeometry.h>
#include <mjin2/priv/WindowRecreation.h>

namespace mjin2
{

class Camera;
class InputListener;
class Scene;
class WindowListener;

namespace priv
{

class Input;

class Window
{
        DISALLOW_COPY_AND_ASSIGN(Window);
    public:
        Window(const String &title,
               const WindowConfig &wc = WindowConfig()) throw ();
        ~Window() throw ();

        void addInputListener(InputListener *listener) throw ();
        void addWindowListener(WindowListener *listener) throw ();
        mjin2::Camera *camera() throw ();
        WindowConfig config() const throw ();
        Vec4 geometry() const throw ();
        void removeInputListener(InputListener *listener) throw ();
        void removeWindowListener(WindowListener *listener) throw ();
        void reportClose() throw ();
        void reportGeometry(const Vec4 &g) throw ();
        void reportRecreation() throw ();
        void run() throw ();
        void setConfig(const WindowConfig &wc) throw ();
        void setMousePosition(s32 x, s32 y) throw ();
        void setScene(mjin2::Scene *scene) throw ();
        void setTimer(mjin2::Timer *timer) throw ();
        void setTitle(const String &title) throw ();
        void stop() throw ();
        String title() const throw ();
        VideoInfo videoInfo() const throw ();

    private:
        void center(u32 width, u32 height, u32 &x, u32 &y) throw ();
        bool configRecreate(const WindowConfig &wc) throw ();
        void restoreScreenResolution() throw ();
        void setConfigKeep(const WindowConfig &wc) throw ();
        void setConfigRecreate(const WindowConfig &wc) throw ();
        void setScreenResolution(u32 width, u32 height) throw ();
        void startViewer() throw ();
        void stopViewer() throw ();

        mjin2::Camera *mCamera;
        osg::ref_ptr<Viewer> mViewer;
        WindowConfig mWC;
        // Restored at the exit if necessary.
        u32 mScreenW;
        u32 mScreenH;
        priv::Input *mInput;
        mjin2::Scene *mScene;
        Vec4 mGeometry;
        bool mIsRunning;
        VideoInfo mVI;
        String mTitle;

        typedef std::vector<WindowListener*> Listeners;
        Listeners mListeners;
        osg::ref_ptr<WindowClose> mWindowClose;
        osg::ref_ptr<WindowGeometry> mWindowGeometry;
        osg::ref_ptr<WindowRecreation> mWindowRecreation;
};

} // namespace priv
} // namespace mjin2

#endif // MJIN2_PRIV_WINDOW_H

